// src/permissions/permissions.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { CreatePermissionDto } from './dto/create-permission.dto';
import { UpdatePermissionDto } from './dto/update-permission.dto'; // 引入更新DTO
import { InjectRepository } from '@nestjs/typeorm';
import { Permission } from './entities/permission.entity';
import { Repository } from 'typeorm';
import * as path from 'node:path';
import { AppException } from '../exceptions/AppException';
import { HttpStatusCodeEnum } from '../enums/http-status-code.enum';

@Injectable()
export class PermissionService {
  private permissionsFolderPath = path.join(
    process.cwd(),
    'src',
    'json',
    'permission.enum.json',
  ); // 枚举文件夹路径

  constructor(
    @InjectRepository(Permission)
    private readonly permissionRepository: Repository<Permission>,
  ) {}

  // 创建权限
  async create(createPermissionDto: CreatePermissionDto): Promise<Permission> {
    const permission = this.permissionRepository.create(createPermissionDto);
    return await this.permissionRepository.save(permission);
  }

  /**
   * 获取指定权限及其子权限的层级结构
   * @param {Permission[]} permissions 所有权限
   * @param {string | null} parentId 父权限ID
   * @returns {Promise<any>} 返回构建好的权限层级
   */
  buildPermissionHierarchyHelper(
    permissions: Permission[],
    parentId: string | null,
  ): any[] {
    const tempPermissions = [];

    // 辅助函数：递归添加子权限
    const addPermissionToParent = (
      parentId: string | null,
      permission: Permission,
    ) => {
      if (!parentId) {
        // 如果没有父权限，说明这是顶层权限
        tempPermissions.push(permission);
      } else {
        // 如果有父权限，查找父权限并添加子权限
        const parentPermission = tempPermissions.find((p) => p.id === parentId);

        if (parentPermission) {
          if (!parentPermission.children) {
            parentPermission.children = [];
          }
          // 添加当前权限到父权限的子权限数组
          parentPermission.children.push(permission);
        } else {
          // 如果找不到父权限，递归调用，尝试添加到更高层级
          const parentPermission = permissions.find((p) => p.id === parentId);
          if (parentPermission) {
            if (!parentPermission.children) {
              parentPermission.children = [];
            }
            parentPermission.children.push(permission);
          }
        }
      }
    };

    // 遍历所有权限，构建多层嵌套
    permissions.forEach((permission) => {
      addPermissionToParent(permission.parent?.id, permission);
    });

    return tempPermissions;
  }

  /**
   * 查找指定权限及其子权限
   * @param {string} permissionId 指定权限ID
   * @returns {Promise<Permission[]>} 返回指定权限及其所有子权限
   */
  async findPermissionHierarchy(permissionId: string): Promise<Permission[]> {
    // 查找所有权限并构建嵌套关系
    const permissions = await this.permissionRepository.find({
      relations: ['parent'], // 关联父级权限
    });

    const hierarchy = this.buildPermissionHierarchyHelper(
      permissions,
      permissionId,
    );

    // 返回嵌套权限
    return hierarchy;
  }

  /**
   * 查找所有权限及其层级结构
   * @returns {Promise<Permission[]>} 返回所有权限的嵌套层级结构
   */
  async findAllPermissionsWithNested(): Promise<Permission[]> {
    const permissions = await this.permissionRepository.find({
      relations: ['parent'], // 关联父级权限
    });

    return this.buildPermissionHierarchyHelper(permissions, null);
  }

  /**
   * 查找所有权限及其层级结构
   * @returns {Promise<Permission[]>} 返回所有权限的嵌套层级结构
   */
  async findAllPermissions(): Promise<Permission[]> {
    const permissions = await this.permissionRepository.find({
      relations: ['parent'], // 关联父级权限
    });

    return permissions;
  }

  // 根据ID查询单个权限以及子权限
  async findOne(targetId: string): Promise<Permission> {
    const permissions = await this.findAllPermissions();

    // 辅助函数：递归查找目标权限及其子权限
    const findPermissionWithChildren = (
      permissions: Permission[],
      targetId: string,
    ): Permission | null => {
      for (const permission of permissions) {
        // 如果找到目标权限，返回该权限及其所有子权限
        if (permission.id === targetId) {
          return permission;
        }

        // 如果当前权限有子权限，递归查找子权限
        if (permission.children && permission.children.length > 0) {
          const foundPermission = findPermissionWithChildren(
            permission.children,
            targetId,
          );
          if (foundPermission) {
            return foundPermission;
          }
        }
      }
      return null; // 如果没有找到，返回 null
    };

    // 调用递归函数查找目标权限
    return findPermissionWithChildren(permissions, targetId);
  }

  // 一键导入权限数据接口
  async importPermissions(): Promise<string> {
    const permissionsData: CreatePermissionDto[] = []; // 用于存储权限数据
    try {
      // 动态导入权限文件
      const permissionModule = await import(this.permissionsFolderPath);
      // console.log('Importing Permission Module:', permissionModule);

      for (const permissionModuleObj of permissionModule) {
        permissionsData.push({
          // id: permissionModuleObj['id'],
          permission_key: permissionModuleObj['permission_key'],
          permission_name: permissionModuleObj['permission_name'], // Renamed to 'permission_name'
          description: permissionModuleObj['description'],
          creator: 'system', // Assuming creator is always system for this case
          remarks: permissionModuleObj['description'], // Remarks can be the same as description or customized
          parent: permissionModuleObj['parent'] || null, // Use the parent_id from the module or set as null
          is_enabled: true, // Defaulting to true, can be changed based on your requirements
          is_deleted: false, // Defaulting to false, can be adjusted based on delete logic
          created_at: new Date(), // Assuming current date/time for creation
          updated_at: new Date(), // Assuming current date/time for update
        });
      }
    } catch (error) {
      console.error('Error importing permission file:', error);
    }

    try {
      // 清空数据库中的权限数据
      await this.clearPermissions();
    } catch (error) {
      console.log('permission.service.ts-importPermissions-error', error);
      throw new AppException(HttpStatusCodeEnum.FOREIGN_KEY_ERROR);
    }

    // 将导入的权限数据保存到数据库
    const permissions = this.permissionRepository.create(permissionsData);
    await this.permissionRepository.save(permissions);

    return 'Permissions imported successfully';
  }

  /**
   * 清空数据权限以及其依赖
   * @returns {Promise<void>}
   */
  async clearPermissions() {
    const queryRunner =
      this.permissionRepository.manager.connection.createQueryRunner();

    await queryRunner.startTransaction();
    try {
      // 删除依赖的记录
      await queryRunner.query(
        'DELETE FROM role_permissions WHERE permission_id IS NOT NULL',
      );

      // 清空权限表
      await queryRunner.query('DELETE FROM permission'); // 假设表名为 `permissions`

      // 提交事务
      await queryRunner.commitTransaction();

      console.log('权限数据已成功清空');
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      console.error('清空权限数据时出错:', error);
    } finally {
      await queryRunner.release();
    }
  }

  // 更新权限
  async update(
    id: string,
    updatePermissionDto: UpdatePermissionDto,
  ): Promise<Permission> {
    const permission = await this.findOne(id); // 先查找权限是否存在
    //
    // // 更新权限的属性
    Object.assign(permission, updatePermissionDto);
    return await this.permissionRepository.save(permission);
  }

  // 删除权限（逻辑删除）
  async remove(id: string): Promise<void> {
    const permission = await this.findOne(id); // 先查找权限是否存在
    permission.is_deleted = true; // 标记为已删除
    await this.permissionRepository.save(permission); // 更新为已删除
  }

  // 永久删除权限
  async hardDelete(id: string): Promise<void> {
    const permission = await this.findOne(id);
    await this.permissionRepository.remove(permission); // 从数据库中完全删除
  }
}
